﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace MegavaniaX.World
{
    [Serializable]
    public class Screen
    {
        
        public const int ScreenHeight = 16;
        public const int ScreenWidth = 16;

        /// <summary>
        /// Number of multiples of ScreenWidth
        /// </summary>
        public int Width;

        /// <summary>
        /// Number of multiples of ScreenHeight
        /// </summary>
        public int Height;

        /// <summary>
        /// multiples of screenwidth
        /// </summary>
        public int OffsetX;

        /// <summary>
        /// multiples of screenHeight
        /// </summary>
        public int OffsetY;
       
        public string ScreenID;

        [ContentSerializerIgnore]
        public List<Transistion> Transistions;

        public Tile[] Tiles;

        public float LeftBound
        {
            get
            {
                return (OffsetX * ScreenWidth) * 16.0f;
            }
        }

        public float RightBound
        {
            get
            {
                return (ScreenWidth * (Width + OffsetX)) * 16.0f;
            }
        }

        public float TopBound
        {
            get
            {
                return (OffsetY * ScreenHeight * 16.0f);
            }
        }

        public float BottomBound
        {
            get
            {
                return ((Height + OffsetY) * ScreenHeight * 16.0f);
            }
        }

        
        public Screen()
        {

        }

        public Screen(Tile[] tiles, int width, int height, string id)
            : this(tiles, width, height, id, null, 0, 0)
        {

        }

        public Screen(Tile[] tiles, int width, int height, string id, List<Transistion> trans, int offsetX, int offsetY)
        {
            Tiles = tiles;
            Width = width;
            Height = height;
            ScreenID = id;
            if (trans == null)
            {
                Transistions = new List<Transistion>();
            }
            else
            {
                Transistions = trans;
            }
            OffsetX = offsetX;
            OffsetY = offsetY;            
        }

        

        public Tile GetTileAt(float x, float y)
        {
            float nonOffsetX = x - LeftBound;
            float nonOffsetY = y - TopBound;
            int tileX = (int)Math.Floor(nonOffsetX / 16); // 16px per tile
            int tileY = (int)Math.Floor(nonOffsetY / 16);

            if (tileX >= Width * ScreenWidth || tileY >= ScreenHeight * Height || tileY < 0 || tileX < 0)
                return null;

            // MegavaniaX.logger.Debug(string.Format("Returning tile index {0}", tileY * (Width * ScreenWidth) + tileX));
            return Tiles[tileY * (Width * ScreenWidth) + tileX];

        }

        public Vector2 GetTileCoords(Tile t)
        {
            return new Vector2(this.LeftBound + (t.Coordinates.X), this.TopBound + (t.Coordinates.Y));
        }


        public bool IsInXRange(float xpos)
        {
            float minPos = this.OffsetX * 16 * 16.0f;
            float maxPos = (this.OffsetX + Width) * 16 * 16.0f;
            return (xpos >= minPos && xpos <= maxPos);
        }

        public bool IsInYRange(float ypos)
        {
            float minPos = this.OffsetY * 16 * 16.0f;
            float maxPos = (this.OffsetY + Height) * 16 * 16.0f;
            return (ypos >= minPos && ypos <= maxPos);
        }



        internal Transistion? GetTransistionIfExists(Tile currentlyInTile)
        {
            // if tile isn't on edge of map, no transition
            if (!(currentlyInTile.X == 0 || currentlyInTile.Y == 0 || currentlyInTile.X == ScreenWidth * Width - 1 || currentlyInTile.Y == ScreenHeight * Height - 1))
                return null;

            // if we're at the right of the map
            if (currentlyInTile.X == ScreenWidth * Width - 1)
            {
                return new Transistion(0, 0, 0, 0, "test", 'R');
            }
            if (currentlyInTile.X == 0)
            {
                return new Transistion(0, 0, 0, 0, "test", 'L');
            }
            if (currentlyInTile.Y == 0)
            {
                return new Transistion(0, 0, 0, 0, "test", 'T');
            }
            if (currentlyInTile.Y == ScreenHeight * Height - 1)
            {
                return new Transistion(0, 0, 0, 0, "test", 'B');
            }


            return null;

            /*
            // dumb cases: no transitions
            if (Transistions == null || Transistions.Count == 0)
                return null;
            // dumb cases: tile isn't on the edge of the map
            if (!(currentlyInTile.X == 0 || currentlyInTile.Y == 0 || currentlyInTile.X == ScreenWidth * Width - 1 || currentlyInTile.Y == ScreenHeight * Height - 1))
                return null;

            Transistion trans = Transistions.FirstOrDefault((t) => t.GetXRange().Contains(currentlyInTile.X) && t.GetYRange().Contains(currentlyInTile.Y));
            if (trans.Equals(default(Transistion))) // no transition
                return null;

            return trans;
             * */
        }

    }

    


}
